package com.springboot.demo.oom;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * OOM内存泄漏
 *
 * 设置堆最大值： -Xmx8m
 *
 * 开启OOM快照： -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:/OomMemoryLeak.hprof
 *
 * 内存可能泄漏：java.lang.OutOfMemoryError: Java heap space
 * 
 * 堆内存不足：java.lang.OutOfMemoryError: GC overhead limit exceeded，
 * 此错误日志会输出异常代码行号，此时加大堆内存可能解决此问题（如果不存在内存泄露的情况），
 * 如果内存加大了之后代码存在内存泄漏则会抛出 java.lang.OutOfMemoryError: Java heap space 异常
 *
 * @author supu
 * @since 2020-06-17 16:08
 **/
public class OomMemoryLeak {
    public static void main(String[] args) throws InterruptedException {
//        new OomMemoryLeak().addUserList();
        new OomMemoryLeak().distinctUsers();
    }

    public List<User> distinctUsers() throws InterruptedException {
        List<User> userList = new ArrayList<>();
        CountDownLatch countDownLatch = new CountDownLatch(1);
        new Thread(() -> {
            for (int i = 0; i < 100; i++) {
                for (int j = 0; j < 10000; j++) {
                    User user = new User();
                    user.setId(j);
                    user.setName("zs"+j);

                    // 不存在user时，加入list
                    if(!userList.contains(user)){
                        userList.add(user);
                    }
                }
            }

            countDownLatch.countDown();
        }).start();

        countDownLatch.await();

        System.out.println("总数据：" + userList.size());
        return userList;
    }

    public void addUserList() {
        List<User> userList = new ArrayList<>();
        
        for (int j = 0; j < 10000; j++) {
            User user = new User();
            user.setId(j);
            user.setName("zs" + j);
            userList.add(user);
        }
           
        System.out.println("总数据：" + userList.size());
    }
}
